package cc.eddic.pratice.programmingparadigms.streampractice.impl;

import cc.eddic.pratice.programmingparadigms.emp02list.impl.EmployeeListLxImpl;
import cc.eddic.pratice.programmingparadigms.emp02list.impl.ResultListGcsImpl;
import cc.eddic.pratice.programmingparadigms.exam.domain.*;
import cc.eddic.pratice.programmingparadigms.exam.impl.ExamServiceLxImpl;
import cc.eddic.pratice.programmingparadigms.streampractice.QuestionAccuracy;
import cc.eddic.pratice.programmingparadigms.streampractice.QuestionAndAnswer;
import cc.eddic.pratice.programmingparadigms.streampractice.ScoreOfStudentAndCategory;
import cc.eddic.pratice.programmingparadigms.streampractice.StreamPractice;
import lombok.Getter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.*;
import java.util.stream.Collectors;

public class StreamPracticeLx1Impl implements StreamPractice {
    private static final Logger log = LoggerFactory.getLogger(ResultListGcsImpl.class);
    ExamServiceLxImpl examServiceLx = new ExamServiceLxImpl();

    @Override
    public List<QuestionAndAnswer> mapToQuestionAndAnswer(List<Question> questionList) {
        Option defaultOption = new Option("", '*', true);
        List<QuestionAndAnswer> questionAndAnswerList = new ArrayList<>();
        questionAndAnswerList = questionList.stream().map(question ->
        {
//            要查找正确选项和内容，可以先创建一个选项的对象
            Option o = question.getOptions().stream().filter(Option::isCorrectAnswer).findFirst()
                    .orElse(defaultOption);
            return new QuestionAndAnswer(question.getNo(), question.getDescription(),
                    o.getChoice(), o.getAnswer());
        })
                .collect(Collectors.toList());

        return questionAndAnswerList;
    }
//    计算题目正确率

    /**
     * 1.拿到所有包含正确答案的question，统计answerlist中答题的学生总数
     * 2.统计一道题有多少学生答对
     * （1）拿到学生答题表importAnswer
     * （2）统计每道题答对的学生数
     * 3.计算每道题的正确率：选项答对的学生总数/答题学生总数
     */
    public List<QuestionAccuracy> calculateAccuracy(List<Answer> answerList) {
//        List<Answer> answerList=examServiceLx.importAnswers("");
        //TODO:统计答题学生总数
        long studengCount=answerList.stream().map(Answer::getStudent).distinct().count();
        /*
//        复杂做法
        Map<String, Integer> studentMap = new HashMap<>();
        for (Answer a : answerList) {
            String studentName = a.getStudent().getName();
            if (studentMap.containsKey(studentName)) {
                studentMap.put(studentName, studentMap.get(studentName) + 1);
            } else {
                studentMap.put(studentName, 1);
            }
        }int studengCount = studentMap.size();
         */

        if (log.isDebugEnabled()) log.debug("李馨：答题学生总数: {}", studengCount);
        //TODO:统计一道题有多少学生答对
        Map<Question, Integer> questionCountMap = new HashMap<>();
        //大流做法
        return answerList.stream().filter(
//                首先判断所选选项和正确选项
                answer -> answer.getChoice() == answer.getQuestion().getOptions()
                        .stream().filter(Option::isCorrectAnswer).findFirst()
                        .orElse(new Option("", '*', true)).getChoice())
//                统计每道题的正确总数
                .collect(Collectors.groupingBy(Answer::getQuestion, Collectors.counting()))
                .entrySet().stream()
//                计算正确率
                .map(qc -> new QuestionAccuracy(qc.getKey().getNo(), qc.getKey().getDescription(),
                        (qc.getValue().intValue() * 1d) / studengCount))
//                按照题号排序
                .sorted(Comparator.comparing(QuestionAccuracy::getNo)).collect(Collectors.toList());
//正确率相同按照题目序号到排序
        /*另一种方法
        answerList.stream().map(answer -> {
            Option option=answer.getQuestion().getOptions().stream().filter(Option::isCorrectAnswer).findFirst()
                    .orElse(new Option("", '*', true));
            System.out.print("Lixin答对的题目选项: {}"+option.getChoice());
            if(option.getChoice()==answer.getChoice()){
                if(questionCountMap.containsKey(answer.getQuestion())){
                    questionCountMap.put(answer.getQuestion(),questionCountMap.get(answer.getQuestion())+1);
                }else{
                    questionCountMap.put(answer.getQuestion(),1);
                }
            }
            if (log.isDebugEnabled()) log.debug("Lixin答对的题目: {}", questionCountMap);
            return questionCountMap;
        }).forEach(x->System.out.print(x.entrySet()));
        for(Question q:questionCountMap.keySet()){
            if (log.isDebugEnabled()) log.debug("Lixin正确率: {}:{}", q.getDescription(),questionCountMap.get(q));
        }
        //TODO:计算正确率
        List<QuestionAccuracy> questionAccuracies=questionCountMap.entrySet().stream().map(qc->new QuestionAccuracy(qc.getKey().getNo(),qc.getKey().getDescription(),
                (qc.getValue()*1.0)/studengCount)).collect(Collectors.toList());
        for(QuestionAccuracy q:questionAccuracies){
            if (log.isDebugEnabled()) log.debug("Lixin正确率aaaaaa: {}", q.getAccuracy());
        }
        return questionAccuracies;*/
    }
    /**
     * 统计每个小类得分情况
     * 1.统计学生的题目分类
     */
    public List<ScoreOfStudentAndCategory> calculateScoreOfStudentAndSubCategory(List<Answer> answerList) {
        return answerList.stream().filter(
//                首先判断所选选项和正确选项
                answer -> answer.getChoice() == answer.getQuestion().getOptions()
                        .stream().filter(Option::isCorrectAnswer).findFirst()
                        .orElse(new Option("", '*', true)).getChoice())
                .collect(Collectors.groupingBy(answer -> answer.getStudent().getName()
                        ,Collectors.groupingBy(answer -> answer.getQuestion().getSubCategory().getName(),Collectors.counting())))
                .entrySet().stream()
                .flatMap(stu->stu.getValue().entrySet().stream()
                        .map(category->new ScoreOfStudentAndCategory(stu.getKey(),category.getKey(),category.getValue().intValue()*4))).collect(Collectors.toList());

/*
//复杂方法
//        统计学生：答对问题对象
        List<StudentAndQuestion> studentAndQuestionList=answerList.stream().filter(
//                首先判断所选选项和正确选项
                answer -> answer.getChoice() == answer.getQuestion().getOptions()
                        .stream().filter(Option::isCorrectAnswer).findFirst()
                        .orElse(new Option("", '*', true)).getChoice())
                .map(a->new StudentAndQuestion(a.getStudent().getName(),a.getQuestion())).collect(Collectors.toList());
        Map<String,List<Question>> stringQuestionMap=new HashMap<>();
        for(StudentAndQuestion studentAndQuestion:studentAndQuestionList){
//            if (log.isDebugEnabled()) log.debug("答对问题的学生和问题: {}+{}", studentAndQuestion.getStudentName(),studentAndQuestion.getQuestion().getDescription());
            if(!stringQuestionMap.containsKey(studentAndQuestion.getStudentName())){
                List<Question> questionList=new ArrayList<>();
                questionList.add(studentAndQuestion.getQuestion());
                stringQuestionMap.put(studentAndQuestion.getStudentName(),questionList);
//                if (log.isDebugEnabled()) log.debug("学生姓名和问题列表{}", studentAndQuestion.getStudentName());
            }else{
                Question e=studentAndQuestion.getQuestion();
                List<Question> newList=stringQuestionMap.get(studentAndQuestion.getStudentName());
                newList.add(e);
                stringQuestionMap.put(studentAndQuestion.getStudentName(),newList);
//                if (log.isDebugEnabled()) log.debug("学生姓名和问题列表{}", studentAndQuestion.getStudentName());
            }
        }

        List<ScoreOfStudentAndCategory> scoreOfStudentAndCategories=new ArrayList<>();
        for(String name:stringQuestionMap.keySet()){
//            if (log.isDebugEnabled()) log.debug("答对学生姓名和问题列表{}+{}", name,stringQuestionMap.get(name).size());

//        将问题分类名字取出来+答对总数
            Map<String,Integer> subCateCount=new HashMap<>();
            for(Question q:stringQuestionMap.get(name)){
//                if (log.isDebugEnabled()) log.debug("答对人名+累呗{}+{}",name,q.getSubCategory().getName());
                if(subCateCount.containsKey(q.getSubCategory().getName())){
                    subCateCount.put(q.getSubCategory().getName(),subCateCount.get(q.getSubCategory().getName())+1);
//                    if (log.isDebugEnabled()) log.debug("问题分类名字取出来+答对总数{}+{}",q.getSubCategory().getName(),subCateCount.get(q.getSubCategory().getName())+1);
                }else{
                    subCateCount.put(q.getSubCategory().getName(),1);
                }
            }

            for(String subCate:subCateCount.keySet()){
                String subName=subCate;
                int score=subCateCount.get(subCate)*4;
                ScoreOfStudentAndCategory scoreOfStudentAndCategory=new ScoreOfStudentAndCategory(name,subName,score);
                if (log.isDebugEnabled()) log.debug("学生名字{}+类别名{}+总分{}",
                        name,subName,score);
                scoreOfStudentAndCategories.add(scoreOfStudentAndCategory);
            }
        }
//        for(String name:stringQuestionMap.keySet()) {
//                String stuName=name;
//
////                if (log.isDebugEnabled()) log.debug("学生名字{}",name);
//
//        }
        return scoreOfStudentAndCategories;*/

    }
@Getter
    static class StudentAndQuestion{
         String studentName;
         Question question;

        public StudentAndQuestion(String studentName, Question question) {
            this.studentName = studentName;
            this.question = question;
        }
    }

}
